1use crate::intrinsics;
2use crate::iter::adapters::SourceIter;
3use crate::iter::adapters::zip::try_get_unchecked;
4use crate::iter::{
5 FusedIterator, TrustedFused, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
6};
7use crate::num::NonZero;
8use crate::ops::Try;
9
10#[derive(Clone, Debug)]
16#[must_use = "iterators are lazy and do nothing unless consumed"]
17#[stable(feature = "rust1", since = "1.0.0")]
18pub struct Fuse<I> {
19 iter: Option<I>,
23}
24impl<I> Fuse<I> {
25 pub(in crate::iter) const fn new(iter: I) -> Fuse<I> {
26 Fuse { iter: Some(iter) }
27 }
28
29 pub(crate) fn into_inner(self) -> Option<I> {
30 self.iter
31 }
32}
33
34#[stable(feature = "fused", since = "1.26.0")]
35impl<I> FusedIterator for Fuse<I> where I: Iterator {}
36
37#[unstable(issue = "none", feature = "trusted_fused")]
38unsafe impl<I> TrustedFused for Fuse<I> where I: TrustedFused {}
39
40#[stable(feature = "rust1", since = "1.0.0")]
43impl<I> Iterator for Fuse<I>
44where
45 I: Iterator,
46{
47 type Item = <I as Iterator>::Item;
48
49 #[inline]
50 fn next(&mut self) -> Option<Self::Item> {
51 FuseImpl::next(self)
52 }
53
54 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
55 FuseImpl::advance_by(self, n)
56 }
57
58 #[inline]
59 fn nth(&mut self, n: usize) -> Option<I::Item> {
60 FuseImpl::nth(self, n)
61 }
62
63 #[inline]
64 fn last(self) -> Option<Self::Item> {
65 match self.iter {
66 Some(iter) => iter.last(),
67 None => None,
68 }
69 }
70
71 #[inline]
72 fn count(self) -> usize {
73 match self.iter {
74 Some(iter) => iter.count(),
75 None => 0,
76 }
77 }
78
79 #[inline]
80 fn size_hint(&self) -> (usize, Option<usize>) {
81 match self.iter {
82 Some(ref iter) => iter.size_hint(),
83 None => (0, Some(0)),
84 }
85 }
86
87 #[inline]
88 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
89 where
90 Self: Sized,
91 Fold: FnMut(Acc, Self::Item) -> R,
92 R: Try<Output = Acc>,
93 {
94 FuseImpl::try_fold(self, acc, fold)
95 }
96
97 #[inline]
98 fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
99 where
100 Fold: FnMut(Acc, Self::Item) -> Acc,
101 {
102 if let Some(iter) = self.iter {
103 acc = iter.fold(acc, fold);
104 }
105 acc
106 }
107
108 #[inline]
109 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
110 where
111 P: FnMut(&Self::Item) -> bool,
112 {
113 FuseImpl::find(self, predicate)
114 }
115
116 #[inline]
117 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
118 where
119 Self: TrustedRandomAccessNoCoerce,
120 {
121 match self.iter {
122 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
125 None => unsafe { intrinsics::unreachable() },
127 }
128 }
129}
130
131#[stable(feature = "rust1", since = "1.0.0")]
132impl<I> DoubleEndedIterator for Fuse<I>
133where
134 I: DoubleEndedIterator,
135{
136 #[inline]
137 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
138 FuseImpl::next_back(self)
139 }
140
141 #[inline]
142 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
143 FuseImpl::advance_back_by(self, n)
144 }
145
146 #[inline]
147 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
148 FuseImpl::nth_back(self, n)
149 }
150
151 #[inline]
152 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
153 where
154 Self: Sized,
155 Fold: FnMut(Acc, Self::Item) -> R,
156 R: Try<Output = Acc>,
157 {
158 FuseImpl::try_rfold(self, acc, fold)
159 }
160
161 #[inline]
162 fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
163 where
164 Fold: FnMut(Acc, Self::Item) -> Acc,
165 {
166 if let Some(iter) = self.iter {
167 acc = iter.rfold(acc, fold);
168 }
169 acc
170 }
171
172 #[inline]
173 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
174 where
175 P: FnMut(&Self::Item) -> bool,
176 {
177 FuseImpl::rfind(self, predicate)
178 }
179}
180
181#[stable(feature = "rust1", since = "1.0.0")]
182impl<I> ExactSizeIterator for Fuse<I>
183where
184 I: ExactSizeIterator,
185{
186 fn len(&self) -> usize {
187 match self.iter {
188 Some(ref iter) => iter.len(),
189 None => 0,
190 }
191 }
192
193 fn is_empty(&self) -> bool {
194 match self.iter {
195 Some(ref iter) => iter.is_empty(),
196 None => true,
197 }
198 }
199}
200
201#[stable(feature = "default_iters", since = "1.70.0")]
202impl<I: Default> Default for Fuse<I> {
203 fn default() -> Self {
234 Fuse { iter: Some(I::default()) }
235 }
236}
237
238#[unstable(feature = "trusted_len", issue = "37572")]
239unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
243
244#[doc(hidden)]
245#[unstable(feature = "trusted_random_access", issue = "none")]
246unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
252
253#[doc(hidden)]
254#[unstable(feature = "trusted_random_access", issue = "none")]
255unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
256where
257 I: TrustedRandomAccessNoCoerce,
258{
259 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
260}
261
262#[doc(hidden)]
267trait FuseImpl<I> {
268 type Item;
269
270 fn next(&mut self) -> Option<Self::Item>;
272 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>;
273 fn nth(&mut self, n: usize) -> Option<Self::Item>;
274 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
275 where
276 Self: Sized,
277 Fold: FnMut(Acc, Self::Item) -> R,
278 R: Try<Output = Acc>;
279 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
280 where
281 P: FnMut(&Self::Item) -> bool;
282
283 fn next_back(&mut self) -> Option<Self::Item>
285 where
286 I: DoubleEndedIterator;
287 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
288 where
289 I: DoubleEndedIterator;
290 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
291 where
292 I: DoubleEndedIterator;
293 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
294 where
295 Self: Sized,
296 Fold: FnMut(Acc, Self::Item) -> R,
297 R: Try<Output = Acc>,
298 I: DoubleEndedIterator;
299 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
300 where
301 P: FnMut(&Self::Item) -> bool,
302 I: DoubleEndedIterator;
303}
304
305#[doc(hidden)]
307impl<I> FuseImpl<I> for Fuse<I>
308where
309 I: Iterator,
310{
311 type Item = <I as Iterator>::Item;
312
313 #[inline]
314 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
315 and_then_or_clear(&mut self.iter, Iterator::next)
316 }
317
318 #[inline]
319 default fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
320 let Some(iter) = &mut self.iter else {
321 return match NonZero::new(n) {
322 Some(n) => Err(n),
323 None => Ok(()),
324 };
325 };
326
327 let res = iter.advance_by(n);
328 if res.is_err() {
329 self.iter = None;
330 }
331 res
332 }
333
334 #[inline]
335 default fn nth(&mut self, n: usize) -> Option<I::Item> {
336 and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
337 }
338
339 #[inline]
340 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
341 where
342 Self: Sized,
343 Fold: FnMut(Acc, Self::Item) -> R,
344 R: Try<Output = Acc>,
345 {
346 if let Some(ref mut iter) = self.iter {
347 acc = iter.try_fold(acc, fold)?;
348 self.iter = None;
349 }
350 try { acc }
351 }
352
353 #[inline]
354 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
355 where
356 P: FnMut(&Self::Item) -> bool,
357 {
358 and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
359 }
360
361 #[inline]
362 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
363 where
364 I: DoubleEndedIterator,
365 {
366 and_then_or_clear(&mut self.iter, |iter| iter.next_back())
367 }
368
369 #[inline]
370 default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
371 where
372 I: DoubleEndedIterator,
373 {
374 let Some(iter) = &mut self.iter else {
375 return match NonZero::new(n) {
376 Some(n) => Err(n),
377 None => Ok(()),
378 };
379 };
380
381 let res = iter.advance_back_by(n);
382 if res.is_err() {
383 self.iter = None;
384 }
385 res
386 }
387
388 #[inline]
389 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
390 where
391 I: DoubleEndedIterator,
392 {
393 and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
394 }
395
396 #[inline]
397 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
398 where
399 Self: Sized,
400 Fold: FnMut(Acc, Self::Item) -> R,
401 R: Try<Output = Acc>,
402 I: DoubleEndedIterator,
403 {
404 if let Some(ref mut iter) = self.iter {
405 acc = iter.try_rfold(acc, fold)?;
406 self.iter = None;
407 }
408 try { acc }
409 }
410
411 #[inline]
412 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
413 where
414 P: FnMut(&Self::Item) -> bool,
415 I: DoubleEndedIterator,
416 {
417 and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
418 }
419}
420
421#[doc(hidden)]
424impl<I> FuseImpl<I> for Fuse<I>
425where
426 I: FusedIterator,
427{
428 #[inline]
429 fn next(&mut self) -> Option<<I as Iterator>::Item> {
430 self.iter.as_mut()?.next()
431 }
432
433 #[inline]
434 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
435 match &mut self.iter {
436 Some(iter) => iter.advance_by(n),
437 None => match NonZero::new(n) {
438 Some(n) => Err(n),
439 None => Ok(()),
440 },
441 }
442 }
443
444 #[inline]
445 fn nth(&mut self, n: usize) -> Option<I::Item> {
446 self.iter.as_mut()?.nth(n)
447 }
448
449 #[inline]
450 fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
451 where
452 Self: Sized,
453 Fold: FnMut(Acc, Self::Item) -> R,
454 R: Try<Output = Acc>,
455 {
456 if let Some(ref mut iter) = self.iter {
457 acc = iter.try_fold(acc, fold)?;
458 }
459 try { acc }
460 }
461
462 #[inline]
463 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
464 where
465 P: FnMut(&Self::Item) -> bool,
466 {
467 self.iter.as_mut()?.find(predicate)
468 }
469
470 #[inline]
471 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
472 where
473 I: DoubleEndedIterator,
474 {
475 self.iter.as_mut()?.next_back()
476 }
477
478 #[inline]
479 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>
480 where
481 I: DoubleEndedIterator,
482 {
483 match &mut self.iter {
484 Some(iter) => iter.advance_back_by(n),
485 None => match NonZero::new(n) {
486 Some(n) => Err(n),
487 None => Ok(()),
488 },
489 }
490 }
491
492 #[inline]
493 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
494 where
495 I: DoubleEndedIterator,
496 {
497 self.iter.as_mut()?.nth_back(n)
498 }
499
500 #[inline]
501 fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
502 where
503 Self: Sized,
504 Fold: FnMut(Acc, Self::Item) -> R,
505 R: Try<Output = Acc>,
506 I: DoubleEndedIterator,
507 {
508 if let Some(ref mut iter) = self.iter {
509 acc = iter.try_rfold(acc, fold)?;
510 }
511 try { acc }
512 }
513
514 #[inline]
515 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
516 where
517 P: FnMut(&Self::Item) -> bool,
518 I: DoubleEndedIterator,
519 {
520 self.iter.as_mut()?.rfind(predicate)
521 }
522}
523
524#[unstable(issue = "none", feature = "inplace_iteration")]
526unsafe impl<I> SourceIter for Fuse<I>
527where
528 I: SourceIter + TrustedFused,
529{
530 type Source = I::Source;
531
532 #[inline]
533 unsafe fn as_inner(&mut self) -> &mut I::Source {
534 unsafe { SourceIter::as_inner(self.iter.as_mut().unwrap_unchecked()) }
538 }
539}
540
541#[inline]
542fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
543 let x = f(opt.as_mut()?);
544 if x.is_none() {
545 *opt = None;
546 }
547 x
548}